iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

來幫昨天做好的骨架補上一些 CSS 樣式與動畫效果。

進一步組合 position: absolutetransform: translate(...) 的話,還可以得到 Drawer 元件唷 ヽ(́◕◞౪◟◕‵)ノ

成品

原始碼
Dialog 展示
Drawer 展示

開發思路

Dialog

將對話框背景設定為 position: fixed 並搭配 width: 100vw; height: 100vh; 達成滿版效果。而 display: flex; 則讓作為子元件的對話框本體可以在背景元件裡頭垂直水平置中。

const defaultBackdropStyle = css({
  width: '100vw',
  height: '100vh',
  position: 'fixed',
  inset: '0',
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  backgroundColor: 'rgba(0, 0, 0, 0.6)',
  animation: `${opacityIn} 0.25s`,
});

對話框本身的動畫效果拆成兩個部分:掛載時從透明逐漸顯現的效果由 opacityIn 負責,而卸載時則是先進行 unmountedAnimation,結束後觸發 DialogBasetransitionend 事件,進而將整個對話框元件自畫面上卸載:

const opacityIn = keyframes`
from {
  opacity: 0;
}
to {
  opacity: 1;
}
`;
const defaultDialogStyle = css({
  margin: '0',
  padding: '24px',
  borderRadius: '8px',
  border: 'none',
  backgroundColor: '#fff',
  animation: `${opacityIn} 0.25s`,
});
const unmountedAnimation = css({
  opacity: '0',
  transition: 'opacity 0.25s',
});

Drawer

透過 props.direction 控制對話框出現的位置,接著根據傳入的 direction 數值來決定對話框的 transform 效果要從哪一個方向開始。需注意 drawerUnmountedAnimation 也要配合 direction 來調整元件卸載前的移除動畫效果。

比如在 Drawerprops.direction = 'right' 時,預設 Drawer 滿版畫面高且靠右(right: 0),並且 drawerUnmountedAnimation 要設定為 transform: translateX(50vw); 來讓 Drawer 消失時要往畫面右側退去,

const defaultDrawerStyle = useMemo(() => {
  // 其他先略過
  return css({
    height: '100vh',
    top: '0',
    right: '0',
    animation: `${slideInRight} 0.25s`,
  });
}, [direction]);
const drawerUnmountedAnimation = useMemo(() => {
  // 其他先略過
  return css({
    transform: 'translateX(50vw)',
    transition: '0.25s ease',
  });
}, [direction]);

對話框背景則是透過 opacityInbackdropUnmountedAnimation 做出淡入淡出效果。

修改指南

目前並未對 DialogDrawer 元件預設 min-width 等數值,有需要的話可以放在 Dialog 元件的 defaultDialogStyleDrawer 元件的 defaultDrawerStyle 中。

自評

比較花時間的地方是處理 props.direction 四個方位對應的 Drawer 動畫效果。邏輯倒是還好 (・∀・) 單純自用的話說不定連 props.direction 都可以不做,直接把樣式寫在 Drawer 裡面就搞定了。


上一篇
day14: DialogBase
下一篇
day16: Portal
系列文
我們可以不要 component library 了嗎?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言